<?php
/*
 ****************************************
 *
 * Snippet Name: NewsManager
 * Short Desc: Manage articles directly from front end (news, blogs, PR, etc.)
 * Created By: xyzvisual
 * Modified By: INFORMATOR Team (www.informator.org) - Lyubomir Kolev
 *
 * Version: 1.4
 * Modified: July 13, 2007
 *
 * Changelog:
 *   July 13, 07 -- FIX problem with hide/show button;
 *   July 13, 07 -- FIX problem with move/remove in menu;
 *   July 13, 07 -- FIX problem with pagination;
 *   July 13, 07 -- MODIFIED pagination;
 *   July 13, 07 -- ADDED two placeholders ([+prevsplitter+], [+nextsplitter+]),
 *                         replacing [+prevnextsplitter+] placeholder;
 *                  EXAMPLE USAGE:
 *               [+previous+][+prevsplitter+][+pages+][+nextsplitter+][+next+]
 *
 ****************************************
 *
 * Description:
 *   Display all owned articles in a table together with buttons
 *   that permit to edit/delete/hide/publisch etc. every single
 *   article in a blog.
 *   !!! Use only one snippet per page !!!
 *
 ****************************************
 *
 * Parameters [default]:
 *   &folder      - folder id where documents are stored
 *   &makefolder  - set to 1 to automatically convert the parent document to a folder. [0]
 *   &postid      - document id to load after working with a news item. [current page]
 *   &editformid  - document id used to modify an article ($_REQUEST['editid'] will hold the id of the document to modify)
 *   &template    - name of template to use for news post
 *   &headertpl   - header template (chunk name) to be inserted at the begining of the news content
 *   &footertpl   - footer template (chunk name) to be inserted at the end of the news content
 *   &rowtpl      - template used to display a single post (chunk name)
 *   &clearcache  - when set to 1 the system will automatically clear the site cache after updating an article.
 *   &nrposts     - number of posts to show per page [10]
 *   &paginate    - paginate [0]
 *   &prv         - chunk to be used inside the previous link ["&lt; Previous"]
 *   &nxt         - chunk to be used inside the next link ["Next &gt;"]
 *   &alwaysshow  - always show previous or next links (if enabled, hyperlink will be removed when prev/next page is not available, | delimiter will not be inserted) [0]
 *   &prevnextsplitter - character delimiter to use to separate previous next links if alwaysshow is 0  ["|"]
 *   &show        - chunk to be used for the show action ["Show"]
 *   &edit        - chunk to be used for the edit action ["Edit"]
 *   &delete      - chunk to be used for the delete action ["Delete"]
 *   &refresh     - chunk to be used for the "move on top" action ["Move on top"]
 *   &publish     - chunk to be used for the publish action ["Publish"]
 *   &unpublish   - chunk to be used for the unpublish action ["Unpublish"]
 *   &showinmenu  - chunk to be used for the "Show in menu" action ["Show in menu"]
 *   &hideinmenu  - chunk to be used for the "Hide in menu" action ["Remove from menu"]
 *   &emptytext   - text to use when no news items are found ["<p>No entries found.</p>"]
 *
 ****************************************
 *
 * Request variables (via GET, POST, or COOKIE):
 *
 *   deleteid      - id of post to delete
 *   refreshid     - id of post for whic the 'createdon' property is set to now, thus effectively putting it at the top of the list
 *   hidemenuid    - id of post for which the 'hidemenu' property must be changed
 *   hidemenuvalue - value to which 'hidemenu' must be set
 *   publishid     - id of post for which the 'published' property must be changed
 *   publishvalue  - value to which 'published' must be set
 *
 ****************************************
 *
 * Important Notes
 *   When in pagination mode (&paginate = 1) always call the snippet uncached in the [!NewsManager!] format
 *   Also, in pagination mode, make sure to use the placeholders for navigation!
 *   To display tv's make sure you use the tv prefix!
 *   For example, if you have the template variable author you would put [+tvauthor+] in your template.
 *
 * Snippet placeholders:
 *   [+sepchar+]    - separator between a document URL and parameters
 *                    (for example [~[*id*]~][+sepchar+]param1=value1&param2=value2)
 *   [+editformid+] - Id of page to use for editing a post
 *   [+pagetitle+]  - current post's page title
 *   [+longtitle+]  - current post's article title
 *   [+id+]         - current post's id
 *   [+edit+]       - text for edit action
 *   [+delete+]     - text for delete action
 *   [+show+]       - text for show action
 *   [+refresh+]    - text for refresh action (update the creation date to now so the post is first in the list)
 *   [+hidemenu+]   - text for hide menu action or show menu action (dependent of the current state of the post)
 *   [+pubish+]     - text for publish action or unpublish action (dependent of the current state of the post)
 *   [+next+]       - text for next action
 *   [+previous+]   - text for previous action
 *   [+prevsplitter+] - splitter if always show is 0
 *   [+nextsplitter+] - splitter if always show is 0
 *   [+pages+]      - page list
 *   [+totalpages+] - total number of pages
 *   [+start+]      - the # of the first item shown
 *   [+stop+]       - the # of the last item shown
 *   [+total+]      - the total # of items on the page
 */

function nm_clear_cache() {
  // empty cache
  if($clearcache==1){
    include_once $modx->config['base_path']."manager/processors/cache_sync.class.processor.php";
    $sync = new synccache();
    $sync->setCachepath("assets/cache/");
    $sync->setReport(false);
    $sync->emptyCache(); // first empty the cache
  }
}

// paginatation enabled or disabled
$paginate = isset($paginate)? $paginate : 0;

// number of posts of which to show per page
$nrposts = isset($nrposts) ? $nrposts : 10;

// get post # to start at
$start = isset($_REQUEST['start'])? $_REQUEST['start'] : 0;

// Are friendly urls enabled?
$furls = $modx->config['friendly_urls'];

// get the chunk code to be used inside the previous <a> tag.
$prv = isset($prv)? $modx->getChunk($prv) : "&lt; Previous";

// get the chunk code to be used inside the next <a> tag.
$nxt = isset($nxt)? $modx->getChunk($nxt) : "Next &gt;";

// determine whether or not to always show previous next links
$alwaysshow = isset($alwaysshow)? $alwaysshow : 0;

// splitter to use of always show is disabled
$prevnextsplitter = isset($prevnextsplitter)? $prevnextsplitter : "|";

// Set the folder to show the news change to what you want or call by snippet
$folder = isset($folder) ? $folder : $modx->documentIdentifier;

// Page used to edit an article
$editformid = isset($editformid) ? $editformid : $modx->documentIdentifier;

// Id of page to goto after user deleted or publiched an article default to this page
$postid = isset($postid) ? $postid : $modx->documentIdentifier;

// Text to be displayed when there are no results
$emptytext = isset($emptytext)? $emptytext : '<p>No entries found.</p>';

// Get values from a post
$deleteid      = (isset($_REQUEST['deleteid'])      ? $_REQUEST['deleteid'] : "");
$refreshid     = (isset($_REQUEST['refreshid'])     ? $_REQUEST['refreshid'] : "");
$hidemenuvalue = (isset($_REQUEST['hidemenuvalue']) ? $_REQUEST['hidemenuvalue'] : "");
$hidemenuid    = (isset($_REQUEST['hidemenuid'])    ? $_REQUEST['hidemenuid'] : "");
$publishvalue  = (isset($_REQUEST['publishvalue'])  ? $_REQUEST['publishvalue'] : "");
$publishid     = (isset($_REQUEST['publishid'])     ? $_REQUEST['publishid'] : "");

// Global placeholders
$showplaceholder = (isset($show) ? $modx->getChunk($show) : "Show");
$editplaceholder = (isset($edit) ? $modx->getChunk($edit) : "Edit");
$deleteplaceholder = (isset($delete) ? $modx->getChunk($delete) : "Delete");
$refreshplaceholder = (isset($refresh) ? $modx->getChunk($refresh) : "Move on top");
$publishplaceholder = (isset($publish) ? $modx->getChunk($publish) : "Publish");
$unpublishplaceholder = (isset($unpublish) ? $modx->getChunk($unpublish) : "Unpublish");
// Modified (13.07.07)
$hideinmenuplaceholder = (isset($hideinmenu) ? $modx->getChunk($hideinmenu) : "Remove from menu");
$showinmenuplaceholder = (isset($showinmenu) ? $modx->getChunk($showinmenu) : "Show in menu");
// -----
$modx->setPlaceHolder('show', $showplaceholder);
$modx->setPlaceHolder('edit', $editplaceholder);
$modx->setPlaceHolder('delete', $deleteplaceholder);
$modx->setPlaceHolder('refresh', $refreshplaceholder);
$modx->setPlaceHolder('editformid', $editformid);
$modx->setPlaceHolder('postid', $postid);
$modx->setPlaceHolder('docid', $modx->documentIdentifier);
$modx->setPlaceHolder('sepchar', ($furls == 1 ? '?' : '&'));

// Row template
$rowtemplate = (isset($rowtpl) ? $modx->getChunk($rowtpl) : "");
if ($rowtemplate == "") {
  $rowtemplate = '
    <div class="[+rowclass+]">
      <!-- Post identification -->
      <div class="nm_title">[+pagetitle+]&nbsp;|&nbsp;[+longtitle+]</div>
      <!-- Actions -->
      <div class="nm_button">
        <!-- Show -->
        <form name="formshow" method="post" action="[~[+id+]~]">
          <input type="submit" class="button" name="show" value="[+show+]" />
        </form>
      </div>
      <div class="nm_button">
        <!-- Edit -->
        <form name="formedit" method="post" action="[~[+editformid+]~]">
          <input name="editid" type="hidden" value="[+id+]" />
          <input type="submit" class="button" name="edit" value="[+edit+]" />
        </form>
      </div>
      <div class="nm_button">
        <!-- Delete -->
        <form name="formdelete[+id+]" method="post" action="">
          <input name="deleteid" type="hidden" value="[+id+]" />
          <input type="submit" onclick="JavaScript: return doDelete[+id+]();" class="button" name="delete" value="[+delete+]" />
        </form>
      </div>
      <div class="nm_button">
        <!-- Move to top of list -->
        <form name="formrefresh" method="post" action="">
          <input name="refreshid" type="hidden" value="[+id+]" />
          <input type="submit" class="button" name="refresh" value="[+refresh+]" />
        </form>
      </div>
      <div class="nm_button">
        <!-- Hide/show in menu -->
        <form name="formhide" method="post" action="">
          <input name="hidemenuvalue" type="hidden" value="[+hidevalue+]" />
          <input name="hidemenuid" type="hidden" value="[+id+]" />
          <input type="submit" class="button" name="hidemenu" value="[+hidemenu+]" />
        </form>
      </div>
      <div class="nm_button">
        <!-- Publish/unpublish -->
        <form name="formpublish" method="post" action="">
          <input name="publishvalue" type="hidden" value="[+publishvalue+]" />
          <input name="publishid" type="hidden" value="[+id+]" />
          <input type="submit" class="button" name="publish" value="[+publish+]" />
        </form>
      </div>
      <!-- Start next post on new row -->
      <span class="nm_eol">&nbsp;</span>
    </div>';
}

// select resources
$tbl = $modx->getFullTableName('site_content');
$rs = $modx->db->select("id, pagetitle, longtitle, published, parent, introtext, createdby, createdon, hidemenu", $tbl, "parent = $folder", "createdon DESC");
if (!$rs) {
  $resource = array();
}
else {
  while ($row = $modx->db->getRow($rs)) {
    $resource[]= $row;
  }
}
$recordcount = count($resource);

$createdon = time();

$rownum = 0;
$output = "";

// Total number of posts to retrieve
$nrtotal = isset($total) ? $total : $recordcount;
$limit = min( $recordcount, $nrtotal );

if ($recordcount < $nrposts)
{
  $stop = $recordcount;
} else {
  $stop = $nrposts;
}

if ($nrtotal > $recordcount) {
  $nrtotal = $recordcount;
}

// Start Pagination
if ($paginate == 1) {
  if ($furls == 0) {
    $char = "&";
  } else if($furls == 1) {
    $char = "?";
  } else {
    $char = '&';
  }

  $currentpageid = $modx->documentIdentifier;
  $next = $start + $nrposts;

  $nextlink = "<a href='[~$currentpageid~]".$char."start=$next'>".$nxt."</a>";
  $previous = $start - $nrposts;
  $previouslink = "<a href='[~$currentpageid~]".$char."start=$previous'>".$prv."</a>";
  $limten = $nrposts + $start;
  if ($alwaysshow == 1) {
    $previousplaceholder = "<span id='nl_off'>".$prv."</span>";
    $nextplaceholder = "<span id='nl_off'>".$nxt."</span>";
  } else {
    $previousplaceholder = "";
    $nextplaceholder = "";
  }
// Modified (13.7.07)
//  $split = "";
  $split_prev = "";
  $split_next = "";

  if ($previous > -1) $split_prev = $prevnextsplitter;
  if ($next < $nrtotal)	$split_next = $prevnextsplitter;
//  if ($previous > -1 && $next < $nrtotal) $split = $prevnextsplitter;
// -----
  if ($previous > -1) $previousplaceholder = $previouslink;
  if ($next < $nrtotal) $nextplaceholder = $nextlink;
  if ($start < $nrtotal) $stop = $limten;
  $limiter = ($limten > $nrtotal) ? $nrtotal : $limten;

  $totalpages = ceil($nrtotal / $nrposts);
// Modified (13.07.07)
  if ($totalpages > 1 ){
    for ($x = 0; $x < $totalpages; $x++) {
      $inc = $x * $nrposts;
      $display = $x + 1;
      if($inc != $start) {
        $pages .= "<a id=\"nl_page\" href='[~$currentpageid~]" . $char . "start=$inc'>&nbsp;".$display."&nbsp;</a>";
      } else {
        $modx->setPlaceholder('current', $display);
		$pages .= "<span id=\"nl_currentpage\">&nbsp;".$display."&nbsp;</span>";
      }
    }
  }
// -----
  $modx->setPlaceholder('next', $nextplaceholder);
  $modx->setPlaceholder('previous', $previousplaceholder);
// Modified (13.07.07)
  $modx->setPlaceholder('prevsplitter', $split_prev);
  $modx->setPlaceholder('nextsplitter', $split_next);
  //$modx->setPlaceholder('prevnextsplitter', $split);
// -----
  $modx->setPlaceholder('start', $start+1);
  $modx->setPlaceholder('stop', $limiter);
  $modx->setPlaceholder('total', $nrtotal);
  $modx->setPlaceholder('pages', $pages);
  $modx->setPlaceholder('totalpages', $totalpages);
}
// End Pagination

if (isset($headertpl)) {
  $output .= $modx->mergePlaceholderContent($modx->mergeChunkContent($modx->getChunk($headertpl)));
}

$output .= (($recordcount < 1) ? $emptytext."\n" : '');

// For all articles
for ($x = $start; $x < $stop; $x++, $rownum++) {
  if ($resource[$x]['createdby'] < 0) {
    // get web user name
    $tbl = $modx->getFullTableName("web_users");
  }
  else {
    // get manager user name
    $tbl = $modx->getFullTableName("manager_users");
  }
  $link = '';

  //perform the query
  $users = $modx->db->select("username", $tbl, "id = '".$resource[$x]['createdby']."'");
  $users_count = $modx->db->getRecordCount($users);
  if ($users_count < 1) {
    $username = "anonymous";
  } else {
    $resourceuser = $modx->fetchRow($users);
    $username     = $resourceuser['username'];
  }

  // Check if user updated this item.
  // We do this here so we're sure that the user is enabled to perform this action,
  // otherwise one could directly call this page with &deleteid=n to cancel any page!
  $tbl= $modx->getFullTableName("site_content");

// Modified (13.07.07)
  //if ($refreshid == $resource[$x]['id']) {
if ($refreshid == $resource[$x]['id'] && $refreshid != "") {
// -----
    $flds = array(
              'createdon' => $createdon,
                         );
    $modx->db->update($flds, $tbl, "id = $refreshid");
    nm_clear_cache();
    $modx->sendRedirect($modx->makeUrl($postid));
  }

// Modified (13.07.07)
  //if ($deleteid == $resource[$x]['id']) {
// -----
  if ($deleteid == $resource[$x]['id'] && $deleteid != "") {
    $modx->db->delete($tbl, "id = $deleteid");
    nm_clear_cache();
    $modx->sendRedirect($modx->makeUrl($postid));
  }

  if ($hidemenuid == $resource[$x]['id'] && $hidemenuvalue != "") {
    // User changed hidemenu
    //$flds = array(
    //          'hidemenu' => $hideMenuValue,
    //                     );
// Modified (13.07.07)
    $flds = array(
              'hidemenu' => $hidemenuvalue,
                         );
// -----
    $modx->db->update($flds, $tbl, "id = $hidemenuid");
    nm_clear_cache();
    $modx->sendRedirect($modx->makeUrl($postid));
  }

  if ($publishid == $resource[$x]['id'] && $publishvalue != "") {
    $flds = array(
              'published' => $publishvalue,
                         );
    $modx->db->update($flds, $tbl, "id = $publishid");
    $modx->sendRedirect($modx->makeUrl($postid));
  }

  // Add function to confirm deletion of this article.
  $output .= '
    <script type="text/javascript" >
      function doDelete'.$resource[$x]['id'].'()
      {
        if(confirm("Delete the article \''.$resource[$x]['pagetitle'].' | '.$resource[$x]['longtitle'].'\'?"))
        {
          return true;
          // document.getElementById("formdelete'.$resource[$x]['id'].'").submit();
        }
        return false;
      }
    </script>';
    // End $output

  // Alternate background colors
  if ($rownum % 2 == 0) {
    $rowclassplaceholder = "nm_row_even";
  }
  else {
    $rowclassplaceholder = "nm_row_odd";
  }

  if ($resource[$x]['hidemenu'] == 1){
    $hidevalueplaceholder = '0';
    $hideplaceholder = $showinmenuplaceholder;
  }
  else {
    $hidevalueplaceholder = '1';
    $hideplaceholder = $hideinmenuplaceholder;
  }

  if ($resource[$x]['published'] == 1){
    $publishvalueplaceholder = '0';
    $publishplaceholder = $unpublishplaceholder;
  }
  else {
    $publishvalueplaceholder = '1';
    $publishplaceholder = $publishplaceholder;
  }

  // Set placeholders for document object
  foreach ($resource[$x] as $docVar => $docVarValue) {
    $modx->setPlaceholder($docVar, $docVarValue);
  }

  // Placeholders for the row
  $modx->setPlaceHolder('rowclass', $rowclassplaceholder);
  $modx->setPlaceHolder('id', $resource[$x]['id']);
// Modified (13.07.07)
  //$modx->setPlaceHolder('hidemenuvalue', $hidevalueplaceholder);
// -----
  $modx->setPlaceHolder('hidevalue', $hidevalueplaceholder);
  $modx->setPlaceHolder('hidemenu', $hideplaceholder);
  $modx->setPlaceHolder('publishvalue', $publishvalueplaceholder);
  $modx->setPlaceHolder('publish', $publishplaceholder);
  $modx->setPlaceHolder('title', $resource[$x]['pagetitle']);
  $modx->setPlaceHolder('pagetitle', $resource[$x]['pagetitle']);
  $modx->setPlaceHolder('longtitle', $resource[$x]['longtitle']);

  // Set tv placeholders
  preg_match_all('~\[\+tv(.*?)\+\]~', $rowtemplate, $matches);
  $cnt = count($matches[1]);
  for($i = 0; $i < $cnt; $i++) {
    $value = $modx->getTemplateVarOutput($idname = array($matches[1][$i]), $docid = $resource[$x]['id'], $published = $resource[$x]['published']);
    $v = $value[$matches[1][$i]];
    $modx->setPlaceholder("tv".$matches[1][$i], $v);
  }

  // Expand the chunk code, and replace Placeholders
// Modified (13.07.07)
  if (isset($resource[$x]['id'])){
    $output .= $modx->mergePlaceholderContent($modx->mergeChunkContent($rowtemplate));
  }
// -----
}

if (isset($footertpl)) {
  $output .= $modx->mergePlaceholderContent($modx->mergeChunkContent($modx->getChunk($footertpl)));
}

return $output;

?>
